﻿/*
 * Autore: Paolo Farina
 */

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media.Imaging;
using RecipesManager.Data;
using RecipesManager.Data.Operations;

namespace RecipesManager.MainControls.ShopSubControls
{
    /// <summary>
    /// Logica di interazione per ShopMainPane.xaml
    /// </summary>

    public class IngredientElems
    {
        public IngredientElems(string name, bool rate)
        {
            NAME = name;
            RATE = rate;
        }

        public string NAME { get; set; }
        public bool RATE { get; set; }

        // override object.Equals
        public override bool Equals(object obj)
        {
            if (obj == null || GetType() != obj.GetType())
            {
                return false;
            }
            if (((IngredientElems)obj).NAME.Equals(this.NAME) && ((IngredientElems)obj).RATE==this.RATE)
                return true;
            return false;
            
        }

        //TODO mi sembra che questo non sia un metodo corretto per calcolare il hashcode.. da confermare
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
    }

    public partial class ShopMainPane : UserControl
    {
        ObservableCollection<IngredientElems> ingrElems = new ObservableCollection<IngredientElems>();
        IShop _shop = null;
        bool _editing = false;

        private bool _fromAnotherWindow;

        public bool FromAnotherWindow
        {
            private get { return _fromAnotherWindow; }
            set
            {
                _fromAnotherWindow = value;
                if (!_fromAnotherWindow) return;
                ingrContainer.IsEnabled = false;
                save_button.ToolTip = Application.Current.FindResource("AddNewShopTooltip");
                save_button.Content = new Image { Source = new BitmapImage(new Uri("../../Icons/document-add.png", UriKind.Relative)) };
            }
        }

        public ShopMainPane(string id)
        {
            InitializeComponent();

            if (id != null && !id.Equals(""))
            {
                this.tb_nomeNegozio.Text = id;
                var shop = Manager.Shops[id];
                _shop = shop;
                _editing = true;
                tb_cittaNegozio.Text = shop.City;
                tb_telefonoNegozio.Text = shop.PhoneNumber;
                tb_indirizzoNegozio.Text = shop.Address;
                tb_orarioNegozio.Text = shop.Timetable;
                ingrElems = new ObservableCollection<IngredientElems>();
                foreach (var ingr in shop.IngredientRatings) ingrElems.Add(new IngredientElems(ingr.Name, Rate_Converter(ingr.Rating)));  
            }

            UpdateInteface(tb_nomeNegozio.Text);

            agg_button.IsEnabled = false;
            canc_button.IsEnabled = false;
            save_button.IsEnabled = false;
        }

        internal void UpdateInteface(string id)
        {
            Mouse.OverrideCursor = System.Windows.Input.Cursors.Wait;
            if (_shop == null) id = "";
            var tmpIngr = new List<string>();

            foreach (var ingredientElemse in ingrElems) tmpIngr.Add(ingredientElemse.NAME);

            cb_ingr.Items.Clear();
            grid_ingr.ItemsSource = ingrElems;
            if (!_fromAnotherWindow)
                cb_ingr.Items.Add(Application.Current.FindResource("ComboBoxAddNewIngredientSuggestion"));
            foreach (var ingredient in Operations.GetAddableIngredientsForShop(id, tmpIngr))
                cb_ingr.Items.Add(ingredient.Name);
            Mouse.OverrideCursor = null;
        }

        private static bool Rate_Converter(ShopRating rate)
        {
            if (rate == ShopRating.Good) return true;
            return false;
        }

        private static ShopRating Rate_Converter(bool rate)
        {
            if (rate) return ShopRating.Good;
            return ShopRating.Bad;
        }

        private bool Is_Modified(int ctrl)
        {
            IShop shop = null;

            if (ctrl==2) return true;
            if (_shop==null) return true;

            shop = _shop;

            if (!shop.PhoneNumber.Equals(tb_telefonoNegozio.Text) ||
                !shop.Address.Equals(tb_indirizzoNegozio.Text) ||
                !shop.City.Equals(tb_cittaNegozio.Text) ||
                !shop.Timetable.Equals(tb_orarioNegozio.Text)) return true;
            
            foreach (var ingr in shop.IngredientRatings) if (!ingrElems.Contains(new IngredientElems(ingr.Name, Rate_Converter(ingr.Rating)))) return true;
            foreach (var ingr in ingrElems) if (!shop.IngredientRatings.Contains(ingr.NAME)) return true;
             
            return false;
        }


        public bool Save()
        {
            try
            {
                if (tb_nomeNegozio.Text.Contains("Nuovo negozio")) throw new Exception("Nome 'Nuovo negozio...' non consentito");
                IShop shop = null;

                if (_editing) shop = Manager.Shops[_shop.Name];
                else shop = Manager.Shops.Add(tb_nomeNegozio.Text);

                save_button.IsEnabled = false;

                shop.Update(tb_nomeNegozio.Text, tb_indirizzoNegozio.Text, tb_cittaNegozio.Text, tb_telefonoNegozio.Text,
                            tb_orarioNegozio.Text);

                var sCancIngr = new List<string>();

                /*Rimuovo gli elementi cancellati --> Ma quanti foreach ci vogliono!*/
                foreach (var ingr in shop.IngredientRatings) if (!ingrElems.Contains(new IngredientElems(ingr.Name, Rate_Converter(ingr.Rating)))) sCancIngr.Add(ingr.Name);
                foreach (var ingr in sCancIngr) shop.IngredientRatings.Remove(ingr);

                /*Aggiungo gli elementi che mancano*/
                foreach (var ingr in ingrElems) if (!shop.IngredientRatings.Contains(ingr.NAME))
                        shop.IngredientRatings.Add(ingr.NAME, Rate_Converter(ingr.RATE));
                _shop = shop;
            }
            catch(Exception e)
            {
                MessageBox.Show(e.Message, "Avviso", MessageBoxButton.OK,
                                MessageBoxImage.Error);
                return false;
            }
            
            
            return true;

        }

        #region ButtonHandler

        void Tb_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (!Is_Modified(0)) save_button.IsEnabled = false;
            else save_button.IsEnabled = true;
        }

        void Tb_TextChanged_Name(object sender, TextChangedEventArgs e)
        {
            if (!Is_Modified(2)) save_button.IsEnabled = false;
            else save_button.IsEnabled = true;
        }

        void Agg_Button_Click(object sender, RoutedEventArgs e)
        {
            
            var tmpIngrSelected = (string) cb_ingr.SelectedItem;
            Agg_Ingredient(tmpIngrSelected);
        }

        void Agg_Ingredient(string id)
        {
            ingrElems.Insert(0, new IngredientElems(id, false));
            cb_ingr.Items.Remove(id);
            if (!Is_Modified(1)) save_button.IsEnabled = false;
            else save_button.IsEnabled = true;
            UpdateInteface(tb_nomeNegozio.Text);
        }

        void Canc_Button_Click(object sender, RoutedEventArgs e)
        {
            List<IngredientElems> tmpList=new List<IngredientElems>();
            foreach (var ingredientElemse in grid_ingr.SelectedItems) tmpList.Add((IngredientElems)ingredientElemse);
            foreach (var ingredientElemse in tmpList) ingrElems.Remove(ingredientElemse);
            foreach (var ingredientElemse in tmpList) if (!cb_ingr.Items.Contains(ingredientElemse.NAME))
                cb_ingr.Items.Add(ingredientElemse.NAME);
            if (!Is_Modified(1)) save_button.IsEnabled = false;
            else save_button.IsEnabled = true;
            UpdateInteface(tb_nomeNegozio.Text);
        }

        void Cb_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            var tmpIngrSelected = (string)cb_ingr.SelectedItem;
            if (tmpIngrSelected != null && !_fromAnotherWindow && tmpIngrSelected.Equals(Application.Current.FindResource("ComboBoxAddNewIngredientSuggestion")))
            {
                var res = (new IngredientSubControls.IngredientAddWindow()).ShowDialog();
                if (res != null && res == true)
                    Agg_Ingredient(Data.Manager.Ingredients.LastAdded.Name);
                else
                    cb_ingr.SelectedItem = null;
            }
            else if (cb_ingr.SelectedItem == null || 
                ingrElems.Contains(new IngredientElems((string)cb_ingr.SelectedItem, true)) ||
                ingrElems.Contains(new IngredientElems((string)cb_ingr.SelectedItem, false))) agg_button.IsEnabled = false;
            else agg_button.IsEnabled = true;
        }

        void Grid_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (grid_ingr.SelectedItem == null) canc_button.IsEnabled = false;
            else canc_button.IsEnabled = true;
            if (!Is_Modified(1)) save_button.IsEnabled = false;
            else save_button.IsEnabled = true;
        }

        private void OnChecked(object sender, RoutedEventArgs e)
        {
            if (!Is_Modified(1)) save_button.IsEnabled = false;
            else save_button.IsEnabled = true;
        }

        #endregion

        void Grid_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            var dataGrid = sender as DataGrid;
            if (dataGrid == null)
                return;

        }
    }
}
